#include "list.h"

/**
 * @brief 链表头节点初始化  
 * 
 * @param L 头节点地址
 * @return true：初始化成功  false:初始化失败
 */
bool InitList(Dul_pLinkList *L)
{
    //申请头节点的内存
    *L = (Dul_pLinkList)calloc(1,sizeof(Dul_LNode));
    if(*L == NULL)
    {
        printf("func:%s,line:%d,fail!", __FUNCTION__,__LINE__);
        return false;
    }

    //头节点成员初始化
    (*L)->next = *L;
    (*L)->prev = *L;

    return true;
}

/**
 * @brief 链表任意位置插入节点数据
 * 
 * @param L 头节点变量
 * @param index 插入的位置  
 * @param e 插入的数据
 * @return true false
 */
bool InsertLinst(Dul_pLinkList L,int index,ElemType e)
{
    if(L == NULL)
        return false;
    int i = 0;
    Dul_pLinkList p = L;

    while(i < index-1 && p->next != L)
    {
        i++;
        p = p->next;
    }

    if(i != index-1)
        return false;

    //申请新节点的内存
    Dul_pLinkList new_node = calloc(1,sizeof(Dul_LNode));
    if(new_node == NULL)
    {
        printf("func:%s,line:%d,fail!", __FUNCTION__,__LINE__);
        return false;
    }

    new_node->data = e;

    new_node->next = p->next;
    p->next->prev = new_node;
    new_node->prev = p;
    p->next = new_node;

    return true;
}

/**
 * @brief 链表任意位置删除节点
 * 
 * @param L 头节点变量
 * @param index 删除的位置
 * @return true false
 */
bool ListDelete(Dul_pLinkList L,int index)
{
    if(L == NULL)
    {
        return false;
    }
    int i = 0;
    Dul_pLinkList p = L;

    while(i < index-1 && p->next != L)
    {
        i++;
        p = p->next;
    }

    if(p->next == L || i != index-1)
        return false;
    
    Dul_pLinkList del_node = p->next;

    p->next = del_node->next;
    del_node->next->prev = p;

    free(del_node);
    L->data--;
    return true;
}

/**
 * @brief 链表的查找
 * 
 * @param L 头节点指针变量
 * @param e 要查找的数据
 * @return Dul_pLinkList 返回数据的地址 
 */
Dul_pLinkList LocateElem(Dul_pLinkList L,ElemType e)
{
    if(L == NULL)
        return NULL;

    Dul_pLinkList p = L->next;
    while(p != L)
    {
        if(p->data == e)
            return p;
        p = p->next;
    }
    return NULL;
}

/**
 * @brief 链表的修改
 * 
 * @param L 头节点指针变量
 * @param index 要修改的位置
 * @param e 修改后的值
 * @return true 修改成功
 * @return false 修改失败
 */
bool ModifyElem(Dul_pLinkList L,int index,ElemType e)
{
    if(L == NULL)
        return false;
    
    int i = 1;
    Dul_pLinkList p = L->next;

    while(i < index && p->next!= L)
    {
        i++;
        p = p->next;
    }

    if(i != index)
    {
        return false;
    }
    p->data = e;
    return true;
}

/**
 * @brief 链表的遍历(正向)
 * 
 * @param L 头节点指针变量
 */
void ShowList(Dul_pLinkList L)
{
    if(L == NULL)
        return;
    
    Dul_pLinkList p = L->next;

    while(p != L)
    {
        // printf("%d->",p->data);
        p = p->next;
    }
    printf("\n");
    return;
}

/**
 * @brief 链表的遍历（反向）
 * 
 * @param L 头节点指针变量
 */
void ShowList_Back(Dul_pLinkList L)
{
    if(L == NULL)
        return;

    Dul_pLinkList p = L->prev;

    while(p != L)
    {
        // printf("%d<-",p->data);
        p = p->prev;
    }
    printf("\n");
}
/**
 * @brief 链表的销毁
 * 
 * @param L 头节点的地址
 */
void ListDestory(Dul_pLinkList *L)
{
    if(*L == NULL)
        return;

    Dul_pLinkList del_node = (*L)->next;
    Dul_pLinkList next_node = NULL;

    while(del_node != *L)
    {
        next_node = del_node->next;  //先保存要释放的那个节点的下一个节点的地址
        free(del_node);
        del_node = next_node;
    }
    free(*L);
    *L = NULL;

    printf("链表销毁成功!\n");
}